package com.krtech.wecard.module.ramble.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.krtech.wecard.framework.exception.BusinessException;
import com.krtech.wecard.framework.model.CommRes;
import com.krtech.wecard.framework.security.Inner;
import com.krtech.wecard.framework.utils.LoginUtil;
import com.krtech.wecard.module.ramble.entity.*;
import com.krtech.wecard.module.ramble.enums.RambleEnums;
import com.krtech.wecard.module.ramble.mapper.RambleDrawLogMapper;
import com.krtech.wecard.module.ramble.mapper.RambleLoginLogMapper;
import com.krtech.wecard.module.ramble.service.*;
import com.krtech.wecard.module.sys.entity.SysKeyValue;
import com.krtech.wecard.module.sys.entity.SysUser;
import com.krtech.wecard.module.sys.service.SysKeyValueService;
import com.krtech.wecard.module.sys.service.SysUserService;
import com.krtech.wecard.utils.DfsUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@RestController
@RequestMapping("/rambleLeaderboard")
@Slf4j
@Api(tags = "佳得乐漫步-排行榜")
public class RambleLeaderboardController {

    @Autowired
    private RambleLeaderboardService leaderboardService;

    @Autowired
    private RambleDrawChanceService drawChanceService;


    @Autowired
    private RambleLoginLogService loginLogService;

    @Autowired
    private RambleLoginLogMapper loginLogMapper;

    @Autowired
    private RambleDrawLogMapper drawLogMapper;

    @Autowired
    private SysKeyValueService keyValueService;


    @Autowired
    private SysUserService userService;

    @Autowired
    private RambleAcceptService acceptService;

    @Autowired
    private RambleDrawLogService drawLogService;

    @Autowired
    private RambleHexiaoLogService hexiaoLogService;

    private static String URL = "https://seemax.cc";

    @ApiOperation(value = "修改地域状态")
    @GetMapping("/turnOff")
    @Inner(value = false)
    public CommRes turnOff(){
        SysKeyValue stepKeyValue = keyValueService.getOne(new QueryWrapper<SysKeyValue>()
                .eq(SysKeyValue.COL_SYS_NAME, RambleEnums.HAS_YUNNAN));

        if (stepKeyValue == null){
            throw new BusinessException("环境变量HAS_YUNNAN未配置，请联系管理员");
        }

        String hasYunnan = stepKeyValue.getSysValue();
        if (hasYunnan.equals("0")){
            stepKeyValue.setSysValue("1");
            keyValueService.updateById(stepKeyValue);
            return CommRes.ok("打开地域限制");
        }else if (hasYunnan.equals("1")){
            stepKeyValue.setSysValue("0");
            keyValueService.updateById(stepKeyValue);
            return CommRes.ok("关闭地域限制");
        }

        throw new BusinessException("未知异常");
    }

    @ApiOperation(value = "导出,time给了就导出步数是指定天数的，不给就导出默认当天", notes = "导出")
    @GetMapping("/export")
    @Inner(value = false)
    public CommRes export(HttpServletRequest request, HttpServletResponse response, String time) {

        SysKeyValue stepKeyValue = keyValueService.getOne(new QueryWrapper<SysKeyValue>()
                .eq(SysKeyValue.COL_SYS_NAME, RambleEnums.STEP));

        if (stepKeyValue == null){
            throw new BusinessException("环境变量step未配置，请联系管理员");
        }

        int step = Integer.parseInt(stepKeyValue.getSysValue());

        List<RambleAccept> acceptList = acceptService.list(new QueryWrapper<RambleAccept>().eq(RambleAccept.COL_ACCEPT_DATE,time));

        List<RambleLoginLog> loginLogList = loginLogService.list();

        List<RambleAccept> allAcceptList = acceptService.list();


        List<SysUser> userList = userService.list();

        String today = DateUtil.today();

        //昨日新增人数和总人数
        int yesterdayPeoplecount = drawLogMapper.getDayCount(time + " 00:00:00", time + " 23:59:59");

        //总人数
        int totalPeopleCount = userService.count();

        List<ExportVo> exportVoList = acceptList.stream().map(accept -> {
            ExportVo exportVo = new ExportVo();
            BeanUtil.copyProperties(accept, exportVo);

            //计算当日的
            Integer todayStep = loginLogList.stream()
                    .filter(one-> one.getPhone().equals(exportVo.getPhone()))
                    .filter(one -> {
                        String formatDate = DateUtil.formatDate(one.getRigisterDate());

                        if (StrUtil.isNotEmpty(time)) {
                            return formatDate.equals(time);
                        } else {
                            return formatDate.equals(today);
                        }
            }).mapToInt(RambleLoginLog::getStepNumber).sum();

            exportVo.setTodayStep(todayStep);

            SysUser sysUser = userService.getOne(new QueryWrapper<SysUser>().eq(SysUser.COL_PHONE,accept.getPhone()));

            exportVo.setNickName(sysUser.getNickName());

            //到给定时间为止的总步数
            int totalStep = loginLogList.stream().filter(one -> one.getPhone().equals(accept.getPhone())).mapToInt(RambleLoginLog::getStepNumber).sum();

            exportVo.setTotalStep(totalStep);

            //计算可领取
            int canAccept = totalStep / step;
            exportVo.setCanAccept(canAccept);

            //计算已领取
            int hasAccept = allAcceptList.stream().filter(one -> one.getPhone().equals(accept.getPhone())).collect(Collectors.toList()).size();
            exportVo.setHasAccept(hasAccept);

            //计算未领取
            exportVo.setNoAccept(canAccept - hasAccept);



            //昨日新增人数和总人数
            exportVo.setYeasterDayAddPerson(yesterdayPeoplecount);
            exportVo.setTotalAddPerson(totalPeopleCount);

            return exportVo;
        }).collect(Collectors.toList());

        DfsUtil dfsUtil = new DfsUtil();
        try {
            File file = FileUtil.createTempFile("佳得乐漫步数据", ".xls", new File("./"), true);
            Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("佳得乐漫步数据","佳得乐漫步数据"), ExportVo.class, exportVoList);
            BufferedOutputStream outputStream = FileUtil.getOutputStream(file);
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
            DfsUtil.DfsFile upload = dfsUtil.upload(file);
            return CommRes.ok(URL+upload.getSrc());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        throw new BusinessException("导出异常");
    }

    @ApiOperation(value = "导出全部", notes = "导出")
    @GetMapping("/exportAll")
    @Inner(value = false)
    public CommRes exportAll() {

        SysKeyValue stepKeyValue = keyValueService.getOne(new QueryWrapper<SysKeyValue>()
                .eq(SysKeyValue.COL_SYS_NAME, RambleEnums.STEP));

        if (stepKeyValue == null){
            throw new BusinessException("环境变量step未配置，请联系管理员");
        }

        int step = Integer.parseInt(stepKeyValue.getSysValue());


        List<RambleLoginLog> loginLogList = loginLogService.list();


        List<RambleAccept> allAcceptList = acceptService.list();

        List<RambleDrawChance> drawChanceList = drawChanceService.list();


        List<SysUser> userList = userService.list();


        List<SysUserExport> exportList = userList.stream().map(user -> {
            SysUserExport userExport = new SysUserExport();
            userExport.setNickName(user.getNickName());
            userExport.setPhone(user.getPhone());
            userExport.setMipOpenId(user.getMipOpenId());

            int totalStep = loginLogList.stream().filter(one -> one.getPhone().equals(user.getPhone())).mapToInt(RambleLoginLog::getStepNumber).sum();
            userExport.setTotalStep(totalStep);

            int hasAccept = allAcceptList.stream().filter(one -> one.getPhone().equals(user.getPhone())).collect(Collectors.toList()).size();
            userExport.setAcceptCount(hasAccept);

            //计算使用步数
            int useStep = hasAccept * step;
            userExport.setUseStep(useStep);

            int remainStep = totalStep - useStep;
            userExport.setRemainStep(remainStep);

            userExport.setFirstTime(user.getCreateTime());

            List<RambleDrawChance> filterChance = drawChanceList.stream().filter(one -> {
                return one.getPhone().equals(user.getPhone());
            }).collect(Collectors.toList());
            if (filterChance.size() > 0){
                RambleDrawChance rambleDrawChance = filterChance.get(0);
                userExport.setDrawChance(rambleDrawChance.getDrawChance());
            }

            return userExport;
        }).collect(Collectors.toList());


        DfsUtil dfsUtil = new DfsUtil();
        try {
            File file = FileUtil.createTempFile("佳得乐漫步总数据", ".xls", new File("./"), true);
            Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("佳得乐漫步总数据","佳得乐漫步总数据"), SysUserExport.class, exportList);
            BufferedOutputStream outputStream = FileUtil.getOutputStream(file);
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
            DfsUtil.DfsFile upload = dfsUtil.upload(file);
            return CommRes.ok(URL+upload.getSrc());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        throw new BusinessException("导出异常");
    }

    @ApiOperation(value = "核销导出", notes = "核销导出")
    @GetMapping("/hexiaoExport")
    @Inner(value = false)
    public CommRes hexiaoExport() {

        List<RambleHexiaoLog> hexiaoLogList = hexiaoLogService.list();

        List<RambleHexiaoLogExport> collect = hexiaoLogList.stream().map(hexiao -> {
            RambleHexiaoLogExport rambleHexiaoLogExport = new RambleHexiaoLogExport();
            BeanUtil.copyProperties(hexiao, rambleHexiaoLogExport);
            return rambleHexiaoLogExport;
        }).collect(Collectors.toList());


        DfsUtil dfsUtil = new DfsUtil();
        try {
            File file = FileUtil.createTempFile("佳得乐漫步核销数据", ".xls", new File("./"), true);
            Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("佳得乐漫步核销数据","佳得乐漫步核销数据"), RambleHexiaoLogExport.class, collect);
            BufferedOutputStream outputStream = FileUtil.getOutputStream(file);
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
            DfsUtil.DfsFile upload = dfsUtil.upload(file);
            return CommRes.ok(URL+upload.getSrc());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        throw new BusinessException("导出异常");
    }

    @GetMapping("/leaderBoard")
    @ApiOperation(value = "排行榜")
    public Page<RambleLeaderboardVo> leaderBoard(Page<RambleLeaderboard> page){
        SysUser userInfo = LoginUtil.getUserInfo();

        //查询chance，更新
//        List<RambleDrawChance> drawChanceList = drawChanceService.list();
        //查询所有排行榜然后更新
//        List<RambleLeaderboard> leaderboardList = leaderboardService.list();

//        List<RambleLeaderboard> updateLeleaderboard = leaderboardList.stream().map(leaderboard -> {
//            List<RambleDrawChance> filterChance = drawChanceList.stream().filter(chance -> {
//                return chance.getPhone().equals(leaderboard.getPhone());
//            }).collect(Collectors.toList());
//            if (filterChance.size() > 0) {
//                RambleDrawChance drawChance = filterChance.get(0);
//                leaderboard.setDrawChance(drawChance.getDrawChance());
//            }
//            return leaderboard;
//        }).collect(Collectors.toList());

//        leaderboardService.updateBatchById(leaderboardList);


        List<RambleLeaderboard> list = leaderboardService.list(new QueryWrapper<RambleLeaderboard>().ne(RambleLeaderboard.COL_TOTAL_STEP,0).orderByDesc(RambleLeaderboard.COL_TOTAL_STEP));
        Page<RambleLeaderboard> searchPage = leaderboardService.page(page,new QueryWrapper<RambleLeaderboard>().ne(RambleLeaderboard.COL_TOTAL_STEP,0).orderByDesc(RambleLeaderboard.COL_TOTAL_STEP));


        List<RambleLeaderboardVo> leaderboardVoList = new ArrayList<>();

        //第几页
        long current = page.getCurrent();
        //一页有多大
        long size = page.getSize();

        //开始参数
        long startOffset = (current - 1) * size;
        long endOffset = (current) * size;

        //本人是否添加
        boolean addHasSelf = false;
        for (int i = 0;i<list.size();i++){
            Integer rank = i + 1;

            RambleLeaderboard leaderboard = list.get(i);

            if (!addHasSelf && leaderboard.getPhone().equals(userInfo.getPhone())){
                RambleLeaderboardVo leaderboardVo = new RambleLeaderboardVo();
                BeanUtil.copyProperties(leaderboard,leaderboardVo);
                leaderboardVo.setRank(rank);
                leaderboardVo.setHasSelf(1);

                leaderboardVoList.add(leaderboardVo);

                addHasSelf = true;
            }

            if (i >= startOffset && i < endOffset){
                if (leaderboard.getPhone().equals(userInfo.getPhone())){
                    //是本人
                    if (!addHasSelf){
                        RambleLeaderboardVo leaderboardVo = new RambleLeaderboardVo();
                        BeanUtil.copyProperties(leaderboard,leaderboardVo);
                        leaderboardVo.setRank(rank);
                        leaderboardVo.setHasSelf(1);

                        leaderboardVoList.add(leaderboardVo);

                        addHasSelf = true;
                    }
                }else {
                    //不是本人
                    RambleLeaderboardVo leaderboardVo = new RambleLeaderboardVo();
                    BeanUtil.copyProperties(leaderboard,leaderboardVo);
                    leaderboardVo.setRank(rank);
                    leaderboardVo.setHasSelf(0);

                    leaderboardVoList.add(leaderboardVo);
                }
            }
        }

        Page<RambleLeaderboardVo> voPage = new Page<>();
        BeanUtil.copyProperties(searchPage,voPage);

        voPage.setRecords(leaderboardVoList);
//        voPage.setTotal(list.size());
//        voPage.setCurrent(page.getCurrent());
//        voPage.setSize(page.getSize());


        return voPage;
    }

    @GetMapping("/getData")
    @ApiOperation(value = "获得我的各种信息")
    public RambleLeaderboardVo getData(){
        return leaderboardService.getData();
    }
}
